package com.shangke.corejava.jdbc.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.shangke.corejava.jdbc.DBHelper;
import com.shangke.corejava.jdbc.bean.Users;
import com.shangke.corejava.jdbc.dao.IUsersDao;

public class UsersDaoImpl implements IUsersDao{

	@Override
	public boolean add(Users param) {
		Connection conn=DBHelper.openConnection();
		PreparedStatement stmt=null;
		try {
			String sql="insert into users(id,name,age,birthdate) values(SEQ_USERS.NEXTVAL,?,?,?)";//?表示占位符
			stmt=conn.prepareStatement(sql);
			stmt.setString(1, param.getName());
			stmt.setInt(2, param.getAge());
			//stmt.setDate(3, new java.sql.Date(param.getBirthDate().getTime()));//保存年月日
			stmt.setTimestamp(3, new java.sql.Timestamp(param.getBirthDate().getTime()));//保存年月日时分秒
			int count=stmt.executeUpdate();//executeUpdate()会返回sql更新数据时更新了多少行，更新行数
			if (count==1) {
				return true;//一个方法内部可有多个return
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			DBHelper.closeAll(null, stmt, conn);
		}
		return false;
	}

	@Override
	public boolean edit(Users param) {
		Connection conn=DBHelper.openConnection();
		PreparedStatement stmt=null;
		try {
			//主键和账号不可以修改
			String sql="update users set age=?,birthdate=? where id=?";//?表示占位符
			stmt=conn.prepareStatement(sql);
			stmt.setString(1, param.getName());
			stmt.setInt(2, param.getAge());
			//stmt.setDate(3, new java.sql.Date(param.getBirthDate().getTime()));//保存年月日
			stmt.setTimestamp(2, new java.sql.Timestamp(param.getBirthDate().getTime()));//保存年月日时分秒
			int count=stmt.executeUpdate();//executeUpdate()会返回sql更新数据时更新了多少行，更新行数
			if (count==1) {
				return true;//一个方法内部可有多个return
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			DBHelper.closeAll(null, stmt, conn);
		}
		return false;
	}

	@Override
	public boolean deleteById(int id) {
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;
		try {
			//根据主键删除数据
		   String sql = " delete from users where id=?";
		   stmt = conn.prepareStatement(sql);
		   stmt.setInt(1, id);
		  int  count=  stmt.executeUpdate();
		   if(count==1) {
			   return true;
		   }
		}catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBHelper.closeAll(null, stmt, conn);
		}
		return false;
	}
	
	@Override
	public int deleteByIds1(int[] ids) {
		int result = 0;
		Connection connection = DBHelper.openConnection();
		PreparedStatement stmt = null;

		// 业务说明：批量删除数据，只要有一条删除失败，则所有的都不删除
		try {
			connection.setAutoCommit(false);// 关闭自动提交 ,开启数据库事务
			String sql = "delete from users where id =?";
			stmt = connection.prepareStatement(sql);
			for (int id : ids) {
				stmt.setInt(1, id);
				stmt.addBatch();// 批量发送 ,每循环一次就是一批数据
			}
			int[] counts = stmt.executeBatch();// 返回一个数组，保存了每批数据更新的情况,每批数据更新的数量(1,0)
			for (int i : counts) {// 统计有多少批数据删除成功
				if (i == 1) {
					result++;
				}
			}
			if (result == ids.length) {
				connection.commit();// 提交事务
				connection.setAutoCommit(true);// 开启(还原)数据库事务
			} else {
				connection.rollback();// 回滚事务
			}

		} catch (SQLException e) {
			e.printStackTrace();
			if (connection != null) {//删除数据，如有部分删除异常，则需要全部回滚
				try {
					connection.rollback();
					connection.setAutoCommit(true);
				} catch (SQLException e1) {
				}
			}

		} finally {
			DBHelper.closeAll(null, stmt, connection);
		}
		return result;
	}

	@Override
	public Users finadById(int id) {
		Users users=null;
		// 1.注册驱动2.建立connection连接
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;// 可以防止sql注入攻击,在批量更新时具有更好的性能
		ResultSet rs = null;
		try {
			//3.打开状态连接
			//编写sql时，如果需要传递参数，使用？号进行占位
			String sql = "select id,name name1,age,birthdate from users where name like ?";//注意不要拼接sql
			stmt = conn.prepareStatement(sql);
			//4.执行sql
			//如果sql有参数，即有？号，需要进行参数填充
			stmt.setInt(1, id);//参数的序号是从1开始的，1表示第一个参数
			rs = stmt.executeQuery();
			//5.对sql执行结果进行处理
			while(rs.next()) {//next()方法从结果集中取出一行数据，如果有数据返回true，没有数据返回false
				int id1 = rs.getInt(1);//可以根据列的序号获取列的数据，列的序号是从1开始的，1表示第一列
				String name = rs.getString("name1");//可以根据列名或列的别名获取列的数据 (有别名用别名，没别名用列名)
				int  age = rs.getInt("age");	
				Date birthDate = rs.getTimestamp("birthdate");
				users = new Users(id1, name, age, birthDate);
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			//6.关闭连接，是否资源
			DBHelper.closeAll(rs, stmt, conn);
		}

		return users;
	}

	@Override
	public List<Users> findAll() {
		List<Users> list = new ArrayList<>();
		// 1.注册驱动2.建立connection连接
		Connection conn = DBHelper.openConnection();
		// Statement statement;//可能造成sql注入攻击
		PreparedStatement stmt = null;// 可以防止sql注入攻击,在批量更新时具有更好的性能
		ResultSet rs = null;
		// statement = conn.createStatement();
		try {
			// 3.打开状态连接
			String sql = "select id,name name1,age,birthdate from users";
			stmt = conn.prepareStatement(sql);
			// 4.执行sql
			rs = stmt.executeQuery();
			// 5.对sql执行结果进行处理
			while (rs.next()) {// next()方法从结果集中取出一行数据，如果有数据返回true，没有数据返回false
				int id = rs.getInt(1);// 可以根据列的序号获取列的数据，列的序号是从1开始的，1表示第一列
				String name = rs.getString("name1");// 可以根据列名或列的别名获取列的数据 (有别名用别名，没别名用列名)
				int age = rs.getInt("age");
				// getTimestamp,返回java.sql.Timestamp,Timestamp是java.util.Date的子类，可以保存： 年月日 时分秒毫秒
				Date birthDate = rs.getTimestamp("birthdate");

				// getDate,返回java.sql.Date,sql.Date是java.util.Date的子类，可以保存： 年月日
				// birthDate = rs.getDate("birthdate");//入学日期，入职日期
				// getTime,返回java.sql.Time,sql.Time是java.util.Date的子类，可以保存： 时分秒
				// birthDate = rs.getTime("birthdate");//班车发车时刻表，飞机的飞行时刻表
				Users users = new Users(id, name, age, birthDate);
				list.add(users);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 6.关闭连接，是否资源
			DBHelper.closeAll(rs, stmt, conn);
		}
		return list;
	}

	@Override
	public List<Users> findByExample(Users paramT) {
		List<Users> list = new ArrayList<>();
		// 1.注册驱动2.建立connection连接
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;// 可以防止sql注入攻击,在批量更新时具有更好的性能
		ResultSet rs = null;
		try {
;
			//3.打开状态连接
			//编写sql时，如果需要传递参数，使用？号进行占位
			//注意不要拼接sql
			String sql = "select id,name,age,birthdate from users where name like ?";
			stmt = conn.prepareStatement(sql);
			stmt.setString(1,"%"+paramT.getName()+"%");
			System.out.println(paramT.getName());
			//4.执行sql
			//如果sql有参数，即有？号，需要进行参数填充
			System.out.println("123");
			rs = stmt.executeQuery();
			//5.对sql执行结果进行处理
			while(rs.next()) {//next()方法从结果集中取出一行数据，如果有数据返回true，没有数据返回false
				int id = rs.getInt(1);//可以根据列的序号获取列的数据，列的序号是从1开始的，1表示第一列
				String name = rs.getString("name");//可以根据列名或列的别名获取列的数据 (有别名用别名，没别名用列名)
				int  age = rs.getInt("age");	
				Date birthDate = rs.getTimestamp("birthdate");
				Users users = new Users(id, name, age, birthDate);
				list.add(users);
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			//6.关闭连接，是否资源
			DBHelper.closeAll(rs, stmt, conn);
		}

		return list;
		
	}

	@Override
	public List<Users> findByPager(int page, int size) {
		List<Users> list = new ArrayList<>();
		// 1.注册驱动2.建立connection连接
		Connection conn = DBHelper.openConnection();
		PreparedStatement stmt = null;// 可以防止sql注入攻击,在批量更新时具有更好的性能
		ResultSet rs = null;
		try {
			//3.打开状态连接
			//编写sql时，如果需要传递参数，使用？号进行占位
			String sql="select * from "+"(select id,name,age,birthdate from users where rownum<?) where rn >=?";//注意不要拼接sql
			stmt = conn.prepareStatement(sql);
			//4.执行sql
			//如果sql有参数，即有？号，需要进行参数填充
			stmt.setInt(1, page*size);
			stmt.setInt(1, (page-1)*size);//参数的序号是从1开始的，1表示第一个参数
			rs = stmt.executeQuery();
			//5.对sql执行结果进行处理
			while(rs.next()) {//next()方法从结果集中取出一行数据，如果有数据返回true，没有数据返回false
				int id = rs.getInt(1);//可以根据列的序号获取列的数据，列的序号是从1开始的，1表示第一列
				String name = rs.getString("name1");//可以根据列名或列的别名获取列的数据 (有别名用别名，没别名用列名)
				int  age = rs.getInt("age");	
				Date birthDate = rs.getTimestamp("birthdate");
				Users users = new Users(id, name, age, birthDate);
				list.add(users);
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			//6.关闭连接，是否资源
			DBHelper.closeAll(rs, stmt, conn);
		}

		return list;
	}

	@Override
	public boolean deleteById(Users param) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int deleteByIds(int[] ids) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int addAll(List<Users> users) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int editAll(List<Users> users) {
		// TODO Auto-generated method stub
		return 0;
	}
}
